import Vue, {
  computed,
  defineComponent,
  getCurrentInstance,
  provide,
  Ref,
  watch,
} from 'vue'
import { createSchemaField, useField } from '@formily/vue'
import { observer } from '@formily/reactive-vue'
import { createForm, ObjectField, onFieldMount, onFieldReact, onFormInit, onFormMount } from '@formily/core'
import * as Components from '@formily/vxe-table/src'
import { inject, ref, shallowRef } from 'vue'
import { RouteParams, useRoute, useRouter } from 'vue-router'
import { Form } from '@formily/vxe-table/src'
import { composeExport, } from '@formily/vxe-table/src/__builtins__'
import { useTableInstance, VXETablePropsSymbol } from '@formily/vxe-table/src/array-table'
import {
  Table, Column, Colgroup, Pager, Select, Option, Optgroup, Grid
} from 'vxe-table'

export interface ILinks {
  name: string
  slots: Array<'RecordForm.Toolbar' | 'a'>
  type: string
  label: string
  linkTo: string
  visible: (params: RouteParams, model: any) => boolean
  props: Record<any, any>
}

export interface IServices {
  name: string
  type: string
  resolver: (params: RouteParams, model: any, action) => void
}

export type IActions = {
  name: string
  type: string
  service: string
  label: string
  visible: (params: RouteParams, model: any) => boolean
  disabled?: (params: RouteParams, model: any) => boolean
  slots: Array<'RecordForm.Toolbar' | 'a'>
  props?: Record<any, any>
} & Record<any, any>

const ServicesSymbol = Symbol.for('BFGRIDAPP__SERVICES')

// 提供domain
export function useDomainModelProvider(domain) {
  const TableRef = useTableInstance()
  provide(VXETablePropsSymbol, ref({ border: true, stripe: true }))
  provide(
    Symbol.for('domainmodel'),
    computed(() => {
      return new domain(TableRef)
    })
  )
}
export function useDomainModel<T>() {
  return inject<Ref<T>>(Symbol.for('domainmodel'))
}

const Link = defineComponent({
  props: {
    name: String,
    type: String,
    label: String,
    linkTo: String, // 需要打开的view的path
  },
  setup(props, { attrs, slots }) {
    const route = useRoute()
    const router = useRouter()
    // TODO::根据不同type渲染不同的组件？ 要不就干脆套娃内部组件只显示外面控制事件
    return () => {
      return (
        <div onClick={() => router.push(props.linkTo)}>{slots.default?.()}</div>
      )
    }
  },
})

const Action = defineComponent({
  props: {
    name: String, // 对应service的名称
    type: String,
    label: String,
    service: String, // 对应的service
  },
  setup(props, { attrs, slots }) {
    const prefixRef = inject('prefix', ref('bf'))
    // 获取对应到的 service
    const servicesRef = inject<Ref<any>>(ServicesSymbol, ref([]))
    const serviceRef = computed(() => {
      return servicesRef.value.find((service) => service.name == props.service)
    })
    // 获取 model
    const modelRef = useDomainModel()

    const route = useRoute()
    return () => {
      const className = prefixRef.value + '__action'
      const actionName = props.name
      const service = serviceRef.value
      const params = route.query
      const model = modelRef.value
      // TODO::model实例还没有获取到
      return (
        <span
          class={className}
          onClick={() => {
            service?.resolver(params, model, props)
          }}
        >
          {slots.default?.()}
        </span>
      )
    }
  },
})

const Pagination = observer(defineComponent({
  props: { value: { type: Object, default: () => ({}) } },
  setup(props, { attrs, slots, emit }) {
    // const prefixCls = `${stylePrefix}-array-table`
    const domainModelRef = useDomainModel<any>()
    const fieldRef = useField<ObjectField>()
    return () => {
      const domainModel = domainModelRef.value
      const pagerConfig = domainModelRef.value.pagerConfig
      console.log(fieldRef.value)
      fieldRef.value.setDataSource(pagerConfig)
      return (
        <Pager
          {...attrs}
          currentPage={pagerConfig.currentPage}
          pageSize={pagerConfig.pageSize}
          total={pagerConfig.total}
          onPageChange={domainModel.handlePagerChange}
        />
      )
    }
  },
}))

const { SchemaField } = createSchemaField({
  components: {
    ...Components,
    BFGridApp: composeExport(
      {},
      {
        Link: Link,
        Action: Action,
        Pager: Pagination
      }
    ),
  },
  scope: {
    // global scope 全局的 scope
    BFPermission: (...args) => {
      console.log('validate permission', args)
      return false
    },
  },
})
// actions: {}, // 按钮
// links: { type: Array }, // 链接
const SchemaAppInner = defineComponent({
  components: { SchemaField },
  props: {
    routes: {}, // 路由触发事件
    views: {}, // 所有对应的视图
    services: {}, // 服务
    schema: { type: Object, default: () => ({}) }, // 渲染区域
  },
  setup(props, { slots }) {
    const modelRef = inject('model', ref())
    const prefixRef = inject('prefix', ref('bf'))
    const $router = useRouter()
    const $route = useRoute()
    const domainModelRef = useDomainModel<any>()
    // schema变更之后form需要被重置
    const formRef = shallowRef(null)
    watch(
      () => props.schema,
      () => {
        formRef.value = createForm({
          effects() {
            onFieldMount('gridapp', (field, form) => {
              form.createObjectField({ name: 'pager', basePath: field.address })
              form.createObjectField({ name: 'selections', basePath: field.address })
            })
            // onFieldMount('*', (field, form) => {
            //   if (field.component[0] == 'ArrayTable') {
            //     field.setComponentProps({
            //       ...field.componentProps
            //     })
            //   }
            // })
          },
          // TODO::看应用场景从modelRef里面继承过来数据
        })
        // 这里需要把form实例透传回去
        domainModelRef.value.attachForm(formRef.value)
      },
      { immediate: true }
    )
    // 提供services给actions消费
    provide(
      ServicesSymbol,
      computed(() => props.services)
    )
    // TODO::提供出services和model供links和actions调用
    return () => {
      const className = prefixRef.value + 'schema-app'
      const model = modelRef.value
      const services = props.services as IServices[]

      // function renderToolbars() { // 渲染 Toolbars
      //   return <div class={`${className}__toolbar`}>
      //     {links // 过滤出来那个links属于这个slot
      //       .filter(link => {
      //         return link.slots.includes('RecordForm.Toolbar')
      //       })
      //       .filter(link => link.visible?.($route.query, model))
      //       .map(link => {
      //         return <button {...link.props} onClick={() => $router.push(link.linkTo)}>{link.label}</button>
      //       })
      //     }
      //     {actions // 过滤出来哪个actions属于这个slot
      //       .filter(action => {
      //         return action.slots.includes('RecordForm.Toolbar')
      //       })
      //       .filter(action => action.visible?.($route.query, model))
      //       .map(action => {
      //         const service = services.find(service => service.name == action.service)
      //         const ComponentType = action.type as any
      //         return <ComponentType {...action.props} onClick={() => service.resolver($route.query, model, action)}>{action.label}</ComponentType>
      //       })
      //     }
      //   </div >
      // }

      const renderTable = () => {
        const schema = props.schema
        // instance scope
        return (
          <Form form={formRef.value}>
            <SchemaField schema={schema} scope={{ $route }}></SchemaField>
          </Form>
        )
      }
      // 根据当前路由的变化（query,params)进行links的修改
      function renderDialog() { }
      function renderDrawer() { }
      return (
        <div class={className}>
          {/* {renderToolbars()} */}
          {renderTable()}
        </div>
      )
    }
  },
})

export const BFGridApp = composeExport(SchemaAppInner, {
  Link: Link,
  Action: Action,
  Pager: Pagination
})
